<?php
declare (strict_types=1);

namespace app\user\logic\user;

use app\admin\logic\system\Config as SystemConfig;
use app\common\exception\LogicException;
use app\common\logic\Verify;
use app\common\model\ShareCode;
use app\user\event\subscribes\user\Account as UserSubscribe;
use app\user\logic\user\{Account as User};
use app\user\model\user\Account as AccountModel;
use app\user\validate\user\Profile as ProfileValidate;
use ArrayObject;
use think\facade\{Db, Event};

/**
 * 个人中心接口类
 */
class Profile
{

    /**
     * 个人中心
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-05-07
     */
    public function index(): array
    {
        // 消息通知
        $unread = $this->getUnreadNum(false);
        // 用户信息
        if (request()->user) {

            $user = request()->user;
            $user->hidden(AccountModel::unnecessaryField());
            //
            $user->need_set_password = $user->password == '' ? 1 : 0;
            //
            $balance = app(Balance::class)->whereUserId($user->id)->findOrEmpty();
            //
            $user->need_set_paypwd = $balance->isEmpty() ? 1 : ($balance->password ? 0 : 1);
            // 余额、收入、积分
            $user->append(['avatarUrl', 'balance', 'income', 'credit', 'vip']);
            // 会员信息
            $user = $user->toArray();
            if ($user['vip_expire_time']) {
                $user['vip_status'] = $user['vip_expire_time'] < time() ? 2 : 1;
            } else {
                $user['vip_expire_time'] = 0;
                $user['vip_status']      = 0;
            }

            // 签到信息
            $punch_in              = app(PunchIn::class)->hasTodayPunchIn(true);
            $user['punch_in']      = $punch_in->isEmpty() ? 0 : 1;
            $user['punch_in_days'] = $punch_in->isEmpty() ? 1 : $punch_in->days;
            // 人脸认证状态
            /** @var Face $face */
            $face                  = app(Face::class);
            $user['face_verified'] = $face->isVerified(request()->mid);

        } else {
            $user = new ArrayObject();
        }
        // 列表
        $center_list = app(Personal::class)->getList();

        return [
            'notify' => $unread,
            'user'   => $user,
            'list'   => $center_list
        ];
    }

    // 三方登录绑定状态查询
    public function thirdloginBindStatus(): array
    {
        // 参数
        $mid        = request()->mid;
        $login_conf = SystemConfig::get('system.package.login', [], request()->mhm_id);
        return [
            [
                'key'  => 'weixin',
                'open' => in_array('weixin', $login_conf) ? 1 : 0,
                'bind' => app(ThirdLogin::class)->isUserBind($mid, 'weixin')
            ],
            [
                'key'  => 'qq',
                'open' => in_array('qq', $login_conf) ? 1 : 0,
                'bind' => app(ThirdLogin::class)->isUserBind($mid, 'qq')
            ],
            [
                'key'  => 'sina',
                'open' => in_array('sina', $login_conf) ? 1 : 0,
                'bind' => app(ThirdLogin::class)->isUserBind($mid, 'sina')
            ],
        ];
    }

    // 三方登录绑定
    public function thirdloginBind($param)
    {
        // 参数
        $mid = request()->mid;

        if ($mid) {
            // 验证数据
            validate(ProfileValidate::class)->scene('bind')->failException()->check($param);
            $type  = $param['type'];
            $oauth = $param['oauth'];
        } else {
            // 验证数据
            validate(ProfileValidate::class)->scene('login_bind')->failException()->check($param);
            $type   = $param['type'];
            $oauth  = $param['oauth'];
            $phone  = $param['phone'];
            $verify = $param['verify'];
            // 验证码验证
            app(Verify::class)->check($phone, 'bind_' . $type, $verify);
        }
        // 检测已绑定
        // $exist_user  = app(ThirdLogin::class)->where('user_id', $mid)->where('type', $type)->value('oauth');
        // if ( $exist_user ) throw new LogicException("用户已绑定其他账号");

        $exist_oauth = app(ThirdLogin::class)->where('oauth', $oauth)->where('type', $type)->findOrEmpty();
        if (!$exist_oauth->isEmpty()) throw new LogicException('此账号已绑定其他用户');

        if ($mid) {
            // 用户直接绑定
            // 用户已绑定
            $exist = app(ThirdLogin::class)->where('user_id', $mid)->where('type', $type)->findOrEmpty();

            if (!$exist->isEmpty()) throw new LogicException('用户已绑定其他账号');

            $param['user_id'] = $mid;
            $param['state']   = '';
            $re               = ThirdLogin::create($param);
            if ($re->isEmpty()) throw new LogicException('绑定失败');

        } else {
            // 登录时绑定
            // 存在用户
            $exist = app(User::class)->with(['avatar_url'])->where('phone', $phone)->findOrEmpty();
            if ($exist->isEmpty()) {
                // 账号不存在，创建账号，返回用户信息
                return $this->createUserAndBind($phone, $param);
            } else {
                // 用户已绑定
                $bound = app(ThirdLogin::class)->where('user_id', $exist->id)->where('type', $type)->findOrEmpty();

                if (!$bound->isEmpty()) throw new LogicException('手机号已绑定其他账号');

                $param['user_id'] = $exist->id;
                $re               = ThirdLogin::create($param);
                if ($re->isEmpty()) throw new LogicException('绑定失败');
                // 账号状态是否正常
                if ($exist->status === 0) throw new LogicException('账号已被禁止登录', '账号被禁用');

                $exist->need_set_password = 0;
                // 如果没有设置密码,提示设置密码
                if ($exist->password == '') {
                    $exist->need_set_password = 1;
                }
                // 登录成功
                Event::subscribe(UserSubscribe::class);
                Event::trigger('UserLogin', $exist);
                // 返回用户信息
                return $exist;
            }
        }
    }

    // 创建用户并绑定
    public function createUserAndBind($phone, $param)
    {
        Db::startTrans();
        try {

            $user = User::create(['phone' => $phone, 'superior_user_id' => ShareCode::getShareUser()]);

            if ($user->isEmpty()) throw new LogicException('绑定失败');

            $user = app(User::class)->with(['avatar_url'])->findOrEmpty($user->id)->hidden(AccountModel::unnecessaryField());

            $user->need_set_password = 1;

            // 绑定
            $param['user_id'] = $user->id;
            $bind             = ThirdLogin::create($param);
            if ($bind->isEmpty()) throw new LogicException('绑定失败');

            // 注册成功
            // 注册积分
            $user->credit_key = 'register';
            $user->rel_pk     = $user->id;
            Event::subscribe(UserSubscribe::class);
            Event::trigger('UserReg', $user);

            Db::commit();

            return $user;

        } catch (LogicException $e) {

            Db::rollback();
            throw new LogicException($e->getMessage());
        }
    }

    // 三方登录解绑
    public function thirdloginBindDelete($param): bool
    {
        // 验证数据
        validate(ProfileValidate::class)->scene('delete_bind')->failException()->check($param);

        // 参数
        $mid    = request()->mid;
        $type   = $param['type'] ?? '';
        $verify = $param['verify'] ?? '';
        $phone  = request()->user->phone;

        // 参数验证
        if (!in_array($type, ['weixin', 'qq', 'sina'])) throw new LogicException('绑定类型错误');

        app(Verify::class)->check($phone, 'unbind_' . $type, $verify);

        $exist = app(ThirdLogin::class)->where('user_id', $mid)->where('type', $type)->findOrEmpty();

        if ($exist->isEmpty()) return true;

        if (!$exist->delete()) throw new LogicException('解绑失败');

        return true;
    }

    public function getUnreadNum($status = true)
    {
        $message = app(NotifyMessage::class)->unreadCount();
        $notify  = app(SystemNotify::class)->unreadCount();
        return $status ? bcadd((string)$message, (string)$notify) : intval(($message || $notify));
    }

}
